var gPlaybackIdx;
var gSmilData;
var gSmilFilePath;

function par(audiosrc, clipbegin, clipend, textsrc, ids)
{
	this.audioSrc=audiosrc;	
	this.clipBegin = clipbegin;
	this.clipEnd = clipend;
	this.textSrc = textsrc;
	this.idValues = ids;
}

//parse a smil file
//	localFile is an nsILocalFile type
function loadsmil(localFile)
{
//    alert("loading smil: " + localFile.path);
	var isPar = false;

	//the file as a stream
	var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].
				            createInstance(Components.interfaces.nsIFileInputStream);
	
	var xmlReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"]
	                          .createInstance(Components.interfaces.nsISAXXMLReader);
	
	fstream.init(localFile, -1, 0, 0);
	var count = 0;
	var listOfPars = new Array();
  	var parid, textsrc, textid, audiosrc, clipbegin, clipend, audioid, ids, pardata;
	
	xmlReader.contentHandler = 
	{
		startElement: function(uri, localName, qName, /*nsISAXAttributes*/ attributes) 
		{
			if (qName == "par")
			{
				isPar = true;
				parid = attributes.getValueFromQName("id");
			}
			if (isPar == true)
			{
				if (qName == "audio")
				{
					var tempsrc = attributes.getValueFromQName("src");
					//this squashes sequences of audio clips into one clip
					//so, we don't support navigation within a text block but at least we're not leaving out anything
					//don't worry, it will all be supported in good time
					if (tempsrc == audiosrc)
					{
						clipend = attributes.getValueFromQName("clip-end");
					}
					else
					{
						audiosrc = attributes.getValueFromQName("src");
						clipbegin = attributes.getValueFromQName("clip-begin"); 
						clipend = attributes.getValueFromQName("clip-end");
						audioid = attributes.getValueFromQName("id");
					}
				}
				else if (qName == "text")
				{
					textsrc = attributes.getValueFromQName("src");
					textid = attributes.getValueFromQName("id");
				}
			}
		},

		endElement: function(uri, localName, qName) 
		{
	    	if (qName == "par")
			{
				isPar = false;
				ids = new Array(parid, textid, audioid);
				pardata = new par(audiosrc, clipbegin, clipend, textsrc, ids);
				listOfPars[count] = pardata;
				count++;
				audiosrc = "";
			}
		},
		
		startDocument: function() {
		// don't care
		},

		  endDocument: function() {
		   	// don't care
		  },

		  characters: function(value) {
		    	// don't care
		  },

		  processingInstruction: function(target, data) {
		    	// don't care
		  },

		  ignorableWhitespace: function(whitespace) {
		    // don't care
		  },

		  startPrefixMapping: function(prefix, uri) {
		    // don't care
		  },

		  endPrefixMapping: function(prefix) {
		    // don't care
		  },

		  // nsISupports
		  QueryInterface: function(iid) {
		    if(!iid.equals(Components.interfaces.nsISupports) &&
		       !iid.equals(Components.interfaces.nsISAXContentHandler))
		      throw Components.results.NS_ERROR_NO_INTERFACE;
		    return this;
		  }
	};

	xmlReader.parseFromStream(fstream,"", "text/xml");
	
	return listOfPars;
}

//should check if the file is already open
function opensmil(filepath)
{	
	gSmilFilePath = filepath;
	gSmilData = loadsmil(filepath, "");
}
function playAtId(id)
{
	//find the ID
	if (id == "") return;
	
	var foundAt = -1;
	for (var i = 0; i<gSmilData.length; i++)
	{
		//each chunk of SMIL data has several IDs associated with it, so look at all of them
		for (var j = 0; j<gSmilData[i].idValues.length; j++)
		{
			if (gSmilData[i].idValues[j] == id)
			{
				foundAt = i;
				break;
			}
		}
		if (foundAt != -1) break;
	}	
	
	if (foundAt != -1) play(gSmilData[foundAt]);
}

function playFromCurrentIndex()
{
  play(gSmilData[gPlaybackIdx]);
}

//start playing from the beginning of the currently loaded smil file
function playFirstPhrase()
{
	gPlaybackIdx = 0;
  	playFromCurrentIndex();
}

function playLastPhrase()
{
	gPlaybackIdx = gSmilData.length - 1;
	play(gSmilData[gPlaybackIdx]);
}
function playNextPhrase()
{
	gPlaybackIdx++;
	if (gPlaybackIdx >= gSmilData.length)
	{
		book.loadNextInSpine();
	}
	else
	{
		play(gSmilData[gPlaybackIdx]);
	}
}

function playPrevPhrase()
{
	gPlaybackIdx--;
	if (gPlaybackIdx < 0)
	{
		book.loadPrevInSpine();
	}
	else
	{
		play(gSmilData[gPlaybackIdx]);
	}
}

//this function sends requests for data to be rendered
//the textfile/audiofile paths are sent as absoute paths
function play(parData)
{
	//show text
	var textfile = Components.classes["@mozilla.org/file/local;1"].
	            createInstance(Components.interfaces.nsILocalFile);
	textfile.initWithFile(gSmilFilePath.parent);
	textfile.appendRelativePath(parData.textSrc);
	
	//play audio
	var audiofile = Components.classes["@mozilla.org/file/local;1"].
				createInstance(Components.interfaces.nsILocalFile);
	audiofile.initWithFile(gSmilFilePath.parent);
	audiofile.appendRelativePath(parData.audioSrc);			

  	showTextThen(textfile, function() {
    	playAudio(audiofile, parData.clipBegin, parData.clipEnd, playNextPhrase);
  	});
}
